using System;
using System.Collections.Generic;
using System.Text;
using Ghasam.Business.Domain.Entity;
using NHibernate;
using NHibernate.Expression;


namespace Ghasam.Business.DAO.Impl
{
    public class InternalAccountingDao : DaoBase<InternalAccounting>, IInternalAccountingDao
    {
         #region IInternalAccountingDao Members

        public int Count()
        {
            ICriteria crit = base.Session.CreateCriteria(typeof(InternalAccounting));
            crit.SetProjection(Projections.Count("Id"));
            return crit.UniqueResult<int>();
        }

        public IList<InternalAccounting> GetAll(string orderby, bool desc, int pageSize, int pageNumber)
        {
            ICriteria crit = base.Session.CreateCriteria(typeof(InternalAccounting));

            if (desc)
                crit.AddOrder(Order.Desc(orderby));
            else
                crit.AddOrder(Order.Asc(orderby));

            return crit.SetMaxResults(pageSize).SetFirstResult(pageSize * pageNumber).List<InternalAccounting>();
        }

        public IList<InternalAccounting> InternalAccountingReport(Item item, SalesPerson salesPerson, InternalAccount account, DateTime? accountingStartDate, DateTime? accountingEndDate, int[] formal) {
            ICriteria cri = Session.CreateCriteria(typeof(InternalAccounting));
            if (item != null)
                cri.Add(Expression.Eq("Item", item));
            if (salesPerson != null)
                cri.Add(Expression.Eq("SalesPerson", salesPerson));
            if (account != null)
                cri.Add(Expression.Eq("Account", account));
            if (accountingStartDate.HasValue)
                cri.Add(Expression.Ge("AccountingDate", accountingStartDate));
            if (accountingEndDate.HasValue)
                cri.Add(Expression.Le("AccountingDate", accountingEndDate));
            cri.Add(Expression.In("AccountingType.Id", formal));
            return cri.List<InternalAccounting>();
        }

        public IList<InternalAccounting> Find(string orderby, bool desc, InternalAccounting accounting, DateTime? StartDate, DateTime? EndDate, int pageSize, int pageNumber) {
            ICriteria crit = base.Session.CreateCriteria(typeof(InternalAccounting));

            Example example = Example.Create(accounting).ExcludeZeroes()
                                .ExcludeNulls()
                                .EnableLike(MatchMode.Anywhere);

            crit.Add(example);

            if ( accounting.Account != null ) 
                crit.Add( Expression.Eq( "Account", accounting.Account ) );

            if ( accounting.AccountingType != null )
                crit.Add( Expression.Eq( "AccountingType", accounting.AccountingType ) );

            if ( accounting.SalesPerson != null )
                crit.Add( Expression.Eq( "SalesPerson", accounting.SalesPerson ) );

            if ( StartDate.HasValue )
                crit.Add( Expression.Ge( "AccountingDate", StartDate.Value ) );

            if ( EndDate.HasValue )
                crit.Add( Expression.Le( "AccountingDate", EndDate.Value ) );

            if (desc)
                crit.AddOrder(Order.Desc(orderby));
            else
                crit.AddOrder(Order.Asc(orderby));

            return crit.SetMaxResults(pageSize).SetFirstResult(pageSize * pageNumber).List<InternalAccounting>();
        }

        public int CountFind(InternalAccounting accounting, DateTime? StartDate, DateTime? EndDate) {
            ICriteria crit = base.Session.CreateCriteria(typeof(InternalAccounting));

            Example example = Example.Create(accounting).ExcludeZeroes()
                                .ExcludeNulls()
                                .EnableLike(MatchMode.Anywhere);

            crit.Add(example);

            if (accounting.Account != null)
                crit.Add(Expression.Eq("Account", accounting.Account));

            if (accounting.AccountingType != null)
                crit.Add(Expression.Eq("AccountingType", accounting.AccountingType));

            if (accounting.SalesPerson != null)
                crit.Add(Expression.Eq("SalesPerson", accounting.SalesPerson));

            if (StartDate.HasValue)
                crit.Add(Expression.Ge("AccountingDate", StartDate.Value));

            if (EndDate.HasValue)
                crit.Add(Expression.Le("AccountingDate", EndDate.Value));
            
            crit.SetProjection(Projections.Count("Id"));
            return crit.UniqueResult<int>();
        }
        public IList<InternalAccounting> SortInternalAccounting(string orderby, bool desc, InternalAccounting accounting, DateTime? StartDate, DateTime? EndDate, int pageSize, int pageNumber, string param, bool asc)
        {

            Order dir = new Order(param, asc);
            ICriteria crit = base.Session.CreateCriteria(typeof(InternalAccounting));

            Example example = Example.Create(accounting).ExcludeZeroes()
                                .ExcludeNulls()
                                .EnableLike(MatchMode.Anywhere);

            crit.Add(example);

            crit.CreateAlias("Item", "item");
            crit.CreateAlias("SalesPerson", "salesPerson");
            crit.CreateAlias("Account", "account");

            if (accounting.Account != null)
                crit.Add(Expression.Eq("Account", accounting.Account));

            if (accounting.AccountingType != null)
                crit.Add(Expression.Eq("AccountingType", accounting.AccountingType));

            if (accounting.SalesPerson != null)
                crit.Add(Expression.Eq("SalesPerson", accounting.SalesPerson));

            if (StartDate.HasValue)
                crit.Add(Expression.Ge("AccountingDate", StartDate.Value));

            if (EndDate.HasValue)
                crit.Add(Expression.Le("AccountingDate", EndDate.Value));

            crit.AddOrder(dir);

            return crit.SetMaxResults(pageSize).SetFirstResult(pageSize * pageNumber).List<InternalAccounting>();
        }
        #endregion
    }
}
